package com.jack.cms.ueditor.hunter;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.jack.cms.core.util.SpringContextHolder;
import com.jack.cms.oss.core.QiniuImageUtils;
import com.jack.cms.ueditor.define.AppInfo;
import com.jack.cms.ueditor.define.BaseState;
import com.jack.cms.ueditor.define.MIMEType;
import com.jack.cms.ueditor.define.MultiState;
import com.jack.cms.ueditor.define.State;

/**
 * 图片抓取器
 * 
 * @author hancong03@baidu.com
 *
 */
public class ImageHunter {

	private String filename = null;
	private List<String> allowTypes = null;
	private long maxSize = -1;

	private List<String> filters = null;

	public ImageHunter(Map<String, Object> conf) {

		this.filename = (String) conf.get("filename");
		this.maxSize = (Long) conf.get("maxSize");
		this.allowTypes = Arrays.asList((String[]) conf.get("allowFiles"));
		this.filters = Arrays.asList((String[]) conf.get("filter"));

	}

	public State capture(String[] list) {

		MultiState state = new MultiState(true);

		for (String source : list) {
			state.addState(captureRemoteData(source));
		}

		return state;

	}

	public State captureRemoteData(String urlStr) {

		HttpURLConnection connection = null;
		URL url = null;
		String suffix = null;

		try {
			url = new URL(urlStr);

			if (!validHost(url.getHost())) {
				return new BaseState(false, AppInfo.PREVENT_HOST);
			}

			connection = (HttpURLConnection) url.openConnection();

			connection.setInstanceFollowRedirects(true);
			connection.setUseCaches(true);

			if (!validContentState(connection.getResponseCode())) {
				return new BaseState(false, AppInfo.CONNECTION_ERROR);
			}

			suffix = MIMEType.getSuffix(connection.getContentType());

			if (!validFileType(suffix)) {
				return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);
			}

			if (!validFileSize(connection.getContentLength())) {
				return new BaseState(false, AppInfo.MAX_SIZE);
			}

			int size = connection.getContentLength();

			QiniuImageUtils qiniuImageUtils= SpringContextHolder.getBean("qiniuImageUtils");
			InputStream inputStream = connection.getInputStream();
			String fileName = qiniuImageUtils.upload(inputStream, this.filename);
			inputStream.close();

			State state = new BaseState(true);
			state.putInfo("size", size);
			state.putInfo("title", fileName);
			state.putInfo("url", qiniuImageUtils.getUrl(fileName));
			state.putInfo("type", suffix);
			state.putInfo("original", this.filename + suffix);
			state.putInfo("source", urlStr);

			return state;

		} catch (Exception e) {
			return new BaseState(false, AppInfo.REMOTE_FAIL);
		}

	}

	private boolean validHost(String hostname) {
		try {
			InetAddress ip = InetAddress.getByName(hostname);

			if (ip.isSiteLocalAddress()) {
				return false;
			}
		} catch (UnknownHostException e) {
			return false;
		}

		return !filters.contains(hostname);

	}

	private boolean validContentState(int code) {

		return HttpURLConnection.HTTP_OK == code;

	}

	private boolean validFileType(String type) {

		return this.allowTypes.contains(type);

	}

	private boolean validFileSize(int size) {
		return size < this.maxSize;
	}

}
